package apibase

import (
	"bridge_viewing/dto"
	"bridge_viewing/enum"
	"bridge_viewing/global"
	"bridge_viewing/interfaces"
	"bridge_viewing/static"
	"bridge_viewing/utils"
	"github.com/gin-gonic/gin"
	"net/http"
)

func Response(ctx *gin.Context, errorObj *enum.ErrorObj, resp interfaces.BaseResponseInterface) {
	if resp == nil {
		resp = &dto.BaseRespParam{
			Code: enum.SUCCESS,
			Msg:  "success",
		}
	} else {
		if resp.GetCode() == 0 {
			resp.SetCode(enum.SUCCESS)
		}
		if resp.GetMsg() == "" {
			resp.SetMsg("success")
		}
	}

	// 手动填充
	resp.SetRequestId(utils.GetRequestId(ctx))
	resp.SetTraceId(utils.GetTraceId(ctx))
	if errorObj != nil {
		resp.SetCode(errorObj.Code)
		resp.SetMsg(errorObj.Msg)
	}
	// 返回
	ctx.JSON(http.StatusOK, resp)
}

func Success(ctx *gin.Context, resp interfaces.BaseResponseInterface) {
	Response(ctx, nil, resp)
	return
}

func Fail(ctx *gin.Context, errorObj *enum.ErrorObj) {
	Response(ctx, errorObj, nil)
}

func GetHandler[T interfaces.BaseRequestInterface, G interfaces.BaseResponseInterface](handler func(T) (G, *enum.ErrorObj)) gin.HandlerFunc {
	return func(c *gin.Context) {
		var reqParam T
		if err := c.ShouldBindJSON(&reqParam); err != nil {
			global.GetLogger().Infof("GetHandler request param is error: %s", err.Error())
			Fail(c, enum.ParamErr)
			return
		}

		// 设置trace id 和 request id
		// 从头部获取trace id 和 request id
		traceId := utils.GetTraceId(c)
		requestId := utils.GetRequestId(c)

		// 如果trace id 没有，用request id 设置 trace id
		if reqParam.GetTraceId() == "" {
			if traceId != "" {
				reqParam.SetTraceId(traceId)
			} else {
				if reqParam.GetRequestId() != "" {
					reqParam.SetTraceId(reqParam.GetRequestId())
				} else {
					reqParam.SetTraceId(requestId)

				}
			}
		}
		if traceId == "" {
			utils.SetTraceId(c, reqParam.GetTraceId())
		}

		reqParam.SetRequestId(requestId)

		//设置当前请求用户id
		if c.GetInt(static.USER_ID_KEY) != 0 {
			reqParam.SetUserId(c.GetInt(static.USER_ID_KEY))
		}

		if respParam, err := handler(reqParam); err != nil {
			Fail(c, err)
		} else {
			//请求成功 设置response 的公共参数
			Success(c, respParam)
		}
	}
}
